/// 接下来是通过例子学习Rust
/// 第一例是注释
/// 基本和c#类似，但是多了个//!用于给模块、函数和crate生成文档
pub fn formatoutput() {
    //格式化输出
    println!("{} days", 32);
    //如果参数多，就需要加标量
    println!("{0},this is {1}. {1},this is {0} ", "Alice", "Bob");
    //还可以命名
    println!(
        "{subject} {verb} {object}",
        object = 32,
        verb = "dog",
        subject = true
    );
    // 可以在 `:` 后面指定特殊的格式：b表示二进制
    println!("{} of {:b} people know binary, the other half don't", 1, 2);
    // 你可以按指定宽度来右对齐文本。
    // 下面语句输出 "     1"，5 个空格后面连着 1。
    println!("{number:>width$}", number = 1, width = 6);
    // 你可以在数字左边补 0。下面语句输出 "000001"。
    println!("{number:>0width$}", number = 1, width = 6);

    // 创建一个包含单个 `i32` 的结构体（structure）。命名为 `Structure`。
    #[allow(dead_code)]
    struct Structure(i32);
    // 但是像结构体这样的自定义类型需要更复杂的方式来处理。
    // 下面语句无法运行。
    //println!("This struct `{}` won't print...", Structure(3));

    let pi = std::f64::consts::PI;
    println!("Pi is roughly {0:.3}", pi);
}
/*
std::fmt 包含多种 traits（trait 有 “特征，特性” 等意思） 来控制文字显示，其中重要的两种 trait 的基本形式如下：
fmt::Debug：使用 {:?} 标记。格式化文本以供调试使用。
fmt::Display：使用 {} 标记。以更优雅和友好的风格来格式化文本。
上例使用了 fmt::Display，因为标准库提供了那些类型的实现。若要打印自定义类型的 文本，需要更多的步骤。
*/

/// 所有的类型，若想用 std::fmt 的格式化 trait 打印出来，都要求实现这个 trait。
/// 自动的实现只为一些类型提供，比如 std 库中的类型。所有其他类型 都必须手动实现。
/// fmt::Debug 这个 trait 使这项工作变得相当简单。所有类型都能推导（derive，即自动创建）fmt::Debug 的实现。
/// 但是 fmt::Display 需要手动实现。
pub fn debug_test() {
    // 这个结构体不能使用 `fmt::Display` 或 `fmt::Debug` 来进行打印。
    #[allow(dead_code)] //允许代码没有调用
    struct UnPrintable(i32);

    // `derive` 属性会自动创建所需的实现，使这个 `struct` 能使用 `fmt::Debug` 打印。
    #[derive(Debug)]
    struct DebugPrintable(i32);
    println!("{0:?}", DebugPrintable(3));
    // 将 `Structure` 放到结构体 `Deep` 中。然后使 `Deep` 也能够打印。
    #[derive(Debug)]
    struct Deep(DebugPrintable);
    // 使用 `derive` 的一个问题是不能控制输出的形式。
    // 假如我只想展示一个 `7` 怎么办？
    println!("Now {:?} will print!", Deep(DebugPrintable(7)).0);
    println!("Now {:?} will print!", Deep(DebugPrintable(7)));
    //所以 fmt::Debug 确实使这些内容可以打印，但是牺牲了一些美感。Rust 也通过 {:#?} 提供了 “美化打印” 的功能：
    #[derive(Debug)]
    struct Person<'a> {
        name: &'a str,
        age: u8,
    }
    let peter = Person {
        name: "peter",
        age: 30,
    };
    println!("{:#?}", peter);
}
/// fmt::Debug 通常看起来不太简洁，因此自定义输出的外观经常是更可取的。
/// 这需要通过 手动实现 fmt::Display 来做到。
/// fmt::Display 采用 {} 标记。
pub fn display_test() {
    use std::fmt;
    struct Structure(i32);
    //为了使用 `{}` 标记，必须手动为类型实现 `fmt::Display` trait。
    impl fmt::Display for Structure {
        // 这个 trait 要求 `fmt` 使用与下面的函数完全一致的函数签名
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            // 仅将 self 的第一个元素写入到给定的输出流 `f`。返回 `fmt:Result`，
            // 此结果表明操作成功或失败。注意 `write!` 的用法和 `println!` 很相似。
            write!(f, "{}", self.0)
        }
    }
    println!("{}", Structure(5));
}
pub fn display_train() {
    use std::fmt;
    #[derive(Debug)]
    struct MinMax(i64, i64);
    impl fmt::Display for MinMax {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "{},{}", self.0, self.1)
        }
    }

    #[derive(Debug)]
    struct Point2D {
        x: f64,
        y: f64,
    }
    impl fmt::Display for Point2D {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "x:{},y:{}", self.x, self.y)
        }
    }

    let minmax = MinMax(0, 14);
    println!("Compare structures:");
    println!("Display: {}", minmax);
    println!("Debug: {:?}", minmax);
    let big_range = MinMax(-300, 300);
    let small_range = MinMax(-3, 3);
    println!(
        "The big range is {big} and the small is {small}",
        small = small_range,
        big = big_range
    );

    let point = Point2D { x: 3.3, y: 7.2 };
    println!("Compare points:");
    println!("Display: {}", point);
    println!("Debug: {:?}", point);

    #[derive(Debug)]
    struct ComplexStruct {
        real: f64,
        imge: f64,
    }
    impl fmt::Display for ComplexStruct {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "{} + {}", self.real, self.imge)
        }
    }
    let complex = ComplexStruct {
        real: 3.3,
        imge: 7.2,
    };
    println!("Compare Complex:");
    println!("Display: {}", complex);
    println!("Debug: {:?}", complex);
}
pub fn display_list() {
    use std::fmt;
    // 定义一个包含单个 `Vec` 的结构体 `List`
    struct List(Vec<i32>);
    impl fmt::Display for List {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            // 使用元组的下标获取值，并创建一个 `vec` 的引用
            let vec = &self.0;

            write!(f, "[")?;
            // 使用 `v` 对 `vec` 进行迭代，并用 `count` 记录迭代次数
            for (index, v) in vec.iter().enumerate() {
                // 对每个元素（第一个元素除外）加上逗号。
                // 使用 `?` 或 `try!` 来返回错误。
                if index != 0 {
                    write!(f, ", ")?;
                }
                write!(f, "{}: {}", index, v)?;
            }
            write!(f, "]")
        }
    }
    let list = List(vec![1, 2, 3]);
    println!("{}", list);
}

pub fn format_test() {
    //use std::fmt::{self,Formatter,Display};
}
